import React, {forwardRef, useEffect, useImperativeHandle, useRef, useState} from "react"
import {VulnerabilityTypePieProps} from "./VulnerabilityTypePieType"
import classNames from "classnames"
import styles from "./VulnerabilityTypePie.module.scss"
import * as echarts from "echarts"
import {useControllableValue, useMemoizedFn, useUpdateEffect} from "ahooks"
import {EChartsOption, SelectChangedEvent} from "../VulnerabilityLevelPie/VulnerabilityLevelPieType"
import {useTheme} from "@/hook/useTheme"
import {getCssVar} from "@/utils/tool"

const dataMapColor = {
    0: {
        selectColor: "rgba(49, 52, 63, 1)",
        color: "rgba(49, 52, 63, 0.3)"
    },
    1: {
        selectColor: "rgba(74, 58, 255, 1)",
        color: "rgba(74, 58, 255, 0.3)"
    },
    2: {
        selectColor: "rgba(150, 45, 255, 1)",
        color: "rgba(150, 45, 255, 0.3)"
    },
    3: {
        selectColor: "rgba(218, 95, 221, 1)",
        color: "rgba(218, 95, 221, 0.3)"
    },
    4: {
        selectColor: "rgba(41, 188, 208, 1)",
        color: "rgba(41, 188, 208, 0.3)"
    },
    5: {
        selectColor: "rgba(53, 216, 238, 1)",
        color: "rgba(53, 216, 238, 0.3)"
    },
    6: {
        selectColor: "rgba(255, 182, 96, 1)",
        color: "rgba(255, 182, 96, 0.3)"
    },
    7: {
        selectColor: "rgba(255, 213, 131, 1)",
        color: "rgba(255, 213, 131, 0.3)"
    },
    8: {
        selectColor: "rgba(224, 198, 253, 1)",
        color: "rgba(224, 198, 253, 0.3)"
    },
    9: {
        selectColor: "rgba(204, 210, 222, 1)",
        color: "rgba(204, 210, 222, 0.3)"
    }
}
export const VulnerabilityTypePie: React.FC<VulnerabilityTypePieProps> = React.memo(
    forwardRef((props, ref) => {
        const {className, list} = props

        const {theme} = useTheme()
        const [selectList, setSelectList] = useControllableValue<string[]>(props, {
            defaultValue: [],
            valuePropName: "selectList",
            trigger: "setSelectList"
        })
        const chartRef = useRef<HTMLDivElement>(null)
        const pieChart = useRef<echarts.ECharts>()
        const richBColor = getCssVar("--Colors-Use-Neutral-Text-4-Help-text")
        const richCColor = getCssVar("--Colors-Use-Neutral-Text-1-Title")
        const optionRef = useRef<EChartsOption>({
            series: [
                {
                    type: "pie",
                    radius: ["40%", "80%"],
                    avoidLabelOverlap: false,
                    legendHoverLink: true,
                    selectedMode: "multiple",
                    selectedOffset: 5,
                    minAngle: 10,
                    itemStyle: {
                        color: (params) => {
                            return dataMapColor[params.dataIndex % Object.keys(dataMapColor).length].color
                        },
                        borderRadius: 4,
                        borderColor: "#fff",
                        borderWidth: 1
                    },
                    label: {
                        show: false,
                        position: "center"
                    },
                    emphasis: {
                        label: {
                            show: true,
                            padding: [4, 8],
                            formatter: ["{c|{c}}", "{b|{b}}"].join("\n"),
                            rich: {
                                b: {
                                    color: richBColor,
                                    fontSize: 14,
                                    fontWeight: 400,
                                    lineHeight: 32
                                },
                                c: {
                                    color: richCColor,
                                    fontSize: 24,
                                    fontWeight: 700,
                                    lineHeight: 36
                                }
                            },
                            width: 84,
                            overflow: "truncate",
                            ellipsis: "..."
                        },
                        itemStyle: {
                            opacity: 0.9
                        }
                    },
                    data: []
                }
            ]
        })
        useImperativeHandle(
            ref,
            () => ({
                onReset,
                onResize: () => {
                    pieChart.current?.resize()
                }
            }),
            []
        )
        const getData = useMemoizedFn(() => {
            return list.map((item, index) => ({
                value: item.Total,
                name: item.Verbose,
                selected: true,
                select: {
                    itemStyle: {
                        color: dataMapColor[index % Object.keys(dataMapColor).length].selectColor
                    }
                }
            }))
        })
        const dataRef = useRef<any[]>([])
        useEffect(() => {
            if (list && list.length > 0) {
                if (!pieChart.current) pieChart.current = echarts.init(chartRef.current)
                if (!!(optionRef.current.series && optionRef.current.series[0])) {
                    dataRef.current = getData()
                    if (optionRef.current.series[0].data.length === 0) {
                        optionRef.current.series[0].data = dataRef.current
                        pieChart.current.setOption(optionRef.current)
                    } else {
                        const newData = dataRef.current.map((ele) => {
                            if (selectList.length === 0) {
                                return ele
                            } else {
                                ele.selected = selectList.includes(ele.name)
                                return ele
                            }
                        })
                        optionRef.current.series[0].data = newData
                        pieChart.current.setOption(optionRef.current, true)
                    }
                }
                pieChart.current.on("selectchanged", onSelectChanged)
            }
            return () => {
                if (pieChart.current) {
                    pieChart.current.off("selectchanged", onSelectChanged)
                    pieChart.current.dispose()
                    pieChart.current = undefined
                }
            }
        }, [list])

        useUpdateEffect(() => {
            if (pieChart.current) {
                optionRef.current.series![0]!.emphasis!.label!.rich!.b!.color = richBColor
                optionRef.current.series![0]!.emphasis!.label!.rich!.c!.color = richCColor
                pieChart.current.setOption(optionRef.current)
            }
        }, [theme])
        useUpdateEffect(() => {
            if (!(optionRef.current.series && optionRef.current.series[0])) return
            optionRef.current.series[0].data = dataRef.current.map((ele) => ({
                ...ele,
                selected: selectList.length == 0 ? true : selectList.includes(ele.name)
            }))
            pieChart.current?.setOption(optionRef.current, true)
        }, [selectList])
        const onReset = useMemoizedFn(() => {
            if (!pieChart.current) return
            if (!!(optionRef.current.series && optionRef.current.series[0])) {
                const data = getData()
                dataRef.current = data
                optionRef.current.series[0].data = dataRef.current
            }
            pieChart.current.setOption(optionRef.current, true)
            setSelectList([])
        })
        const onSelectChanged = useMemoizedFn((value) => {
            const {fromAction, fromActionPayload} = value as any as SelectChangedEvent
            const {dataIndexInside} = fromActionPayload
            //不额外处理全选
            if (fromAction === "toggleSelect") {
                return
            }
            const data = dataRef.current
            const selectName = data[dataIndexInside].name // 图上显示的值
            let newSelect = [...selectList]
            if (selectList.length === 0 && fromAction === "unselect" && pieChart.current) {
                /**当初始没有任何选中的时候,第一次点击，选中点击项，其余项变未选中 */
                newSelect.push(selectName)
            } else {
                switch (fromAction) {
                    case "select":
                        if (newSelect.length > 0 && newSelect.includes(selectName)) return
                        newSelect.push(selectName)
                        break
                    case "unselect":
                        newSelect = selectList.filter((ele) => ele != selectName)
                        break
                    default:
                        break
                }
            }

            setSelectList(newSelect)
        })
        const onSelectList = useMemoizedFn((isSelect, index) => {
            const selectItem = {
                type: isSelect ? "unselect" : "select",
                seriesIndex: 0, // 选择第一个系列
                dataIndexInside: index // 选择数据项
            }
            pieChart.current?.dispatchAction({
                ...selectItem
            })
        })
        return (
            <div className={styles["vulnerability-type-pie-container"]}>
                <div className={classNames(styles["vulnerability-type-pie"], className)} ref={chartRef}></div>
                <div className={styles["vulnerability-type-pie-list"]}>
                    {list.map((ele, index) => {
                        const isSelect = selectList.length === 0 || selectList.includes(ele.Verbose)
                        return (
                            <div
                                className={classNames(styles["vulnerability-type-pie-list-item"], {
                                    [styles["vulnerability-type-pie-list-item-selected"]]: isSelect
                                })}
                                onClick={(e) => onSelectList(isSelect, index)}
                                key={ele.Verbose}
                            >
                                <div className={classNames(styles["vulnerability-type-pie-list-item-name"])}>
                                    <div
                                        className={classNames(
                                            styles["vulnerability-type-pie-list-item-radius"],
                                            styles[`bg-color-${index}`]
                                        )}
                                    />
                                    <div className='content-ellipsis'>{ele.Verbose}</div>
                                </div>
                                <div>{ele.Total}</div>
                            </div>
                        )
                    })}
                </div>
            </div>
        )
    })
)
